package cn.schoolwow.quickdao.module.database.ddl.action.flow.column;

import cn.schoolwow.quickdao.domain.QuickDAOConfig;
import cn.schoolwow.quickdao.domain.entity.PropertyOption;
import cn.schoolwow.quickdao.domain.provider.DatabaseProvider;
import cn.schoolwow.quickdao.module.database.ddl.query.service.index.HasConstraintFlow;
import cn.schoolwow.quickdao.module.database.parent.flow.executor.ExecuteUpdateConnectionFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;

public class CreateForeignKeyFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        checkConstraintExist(flowContext);
        executeCreateForeignKey(flowContext);
    }

    @Override
    public String name() {
        return "创建外键约束";
    }

    private void checkConstraintExist(FlowContext flowContext) throws Exception {
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);
        String tableName = (String) flowContext.checkData("tableName");
        PropertyOption propertyOption = (PropertyOption) flowContext.checkData("propertyOption");

        String foreignKeyName = "FK_" + tableName + "_" + propertyOption.foreignKey.field() + "_" + quickDAOConfig.getEntityByClassName(propertyOption.foreignKey.table().getName()).tableName + "_" + propertyOption.name;
        boolean hasResult = (boolean) flowContext.startFlow(new HasConstraintFlow())
                .putTemporaryData("constraintName", foreignKeyName)
                .execute()
                .checkData("hasResult");
        if(hasResult){
            flowContext.broken("外键约束已存在");
        }else{
            flowContext.putTemporaryData("foreignKeyName", foreignKeyName);
        }
    }

    private void executeCreateForeignKey(FlowContext flowContext){
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);
        String tableName = (String) flowContext.checkData("tableName");
        PropertyOption propertyOption = (PropertyOption) flowContext.checkData("propertyOption");
        String foreignKeyName = (String) flowContext.checkData("foreignKeyName");

        DatabaseProvider databaseProvider = quickDAOConfig.databaseContext.databaseProvider;

        String sourceTableName = quickDAOConfig.getEntityByClassName(propertyOption.foreignKey.table().getName()).tableName;
        String sourceTableColumnName = propertyOption.foreignKey.field();
        String reference = databaseProvider.escape(sourceTableName) + "(" + databaseProvider.escape(sourceTableColumnName) + ")" +
                " ON UPDATE " + propertyOption.foreignKey.updateForeignKeyOption().getOperation() +
                " ON DELETE " + propertyOption.foreignKey.deleteForeignKeyOption().getOperation();
        String createForeignKeySQL = "alter table " + quickDAOConfig.databaseContext.databaseProvider.escape(tableName) + "" +
                " add constraint " + databaseProvider.escape(foreignKeyName) +
                " foreign key(" + databaseProvider.escape(propertyOption.column) + ")" +
                " references " + reference + ";";

        flowContext.startFlow(new ExecuteUpdateConnectionFlow())
                .putTemporaryData("name", "创建外键约束")
                .putTemporaryData("sql", createForeignKeySQL)
                .execute();
    }
}
